#include "LuaSyntaxHighlighter.h"

LuaSyntaxHighlighter::LuaSyntaxHighlighter(QTextDocument *parent): QSyntaxHighlighter(parent)
{
    HighlightingRule rule;

    //对于下面正则表达式，标记为紫色，类名称
    class_format_.setFontWeight(QFont::Bold);
    class_format_.setForeground(Qt::darkMagenta);
    rule.pattern = QRegularExpression("\\b[A-Za-z]+:\\b");
    rule.format = class_format_;
    highlighting_rule_rules_.append(rule);
    rule.pattern = QRegularExpression("\\b[A-Za-z]+\\.\\b");
    rule.format = class_format_;
    highlighting_rule_rules_.append(rule);

    //字符串，标记深红色
    quotation_format_.setForeground(Qt::darkRed);
    rule.pattern = QRegularExpression("\".*\"");
    rule.format = quotation_format_;
    highlighting_rule_rules_.append(rule);
    rule.pattern = QRegularExpression("'.*'");
    rule.format = quotation_format_;
    highlighting_rule_rules_.append(rule);

    //函数标记蓝色
    //function_format_.setFontItalic(true);
    function_format_.setForeground(Qt::blue);
    rule.pattern = QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()");
    rule.format = function_format_;
    highlighting_rule_rules_.append(rule);

    //关键字
    QStringList keywords = {"and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or",
                            "repeat", "return", "then", "true", "unitl", "while", "goto"};
    //对于下面关键字部分，标记为深蓝色
    keyword_format_.setForeground(Qt::darkBlue);
    keyword_format_.setFontWeight(QFont::Bold);
    for (int i = 0; i < keywords.length(); i++)
    {
        QString pattern = "\\b" + keywords[i] + "\\b";
        rule.pattern = QRegularExpression(pattern);
        rule.format = keyword_format_;
        highlighting_rule_rules_.append(rule);
    }

    //对于下面正则表达式，单行注释标记为绿色
    single_line_comment_format_.setForeground(Qt::darkGreen);
    single_line_comment_format_.setFontItalic(true);
    rule.pattern = QRegularExpression("--[^\n]*");
    rule.format = single_line_comment_format_;
    highlighting_rule_rules_.append(rule);

    //对于多行注释
    multi_line_comm_format_.setForeground(Qt::darkGreen);
    multi_line_comm_format_.setFontItalic(true);
    comment_start_expression_ = QRegularExpression("--\\[\\[");
    comment_end_expression_ = QRegularExpression("\\]\\]");
}

LuaSyntaxHighlighter::~LuaSyntaxHighlighter() = default;

void LuaSyntaxHighlighter::highlightBlock(const QString &text)
{
    for (const auto &[pattern, format]: highlighting_rule_rules_)
    {
        QRegularExpressionMatchIterator match_iterator = pattern.globalMatch(text);
        while (match_iterator.hasNext())
        {
            QRegularExpressionMatch match = match_iterator.next();
            setFormat(match.capturedStart(), match.capturedLength(), format);
        }
    }

    setCurrentBlockState(0);

    // 处理多行注释
    int start_index = 0;
    if (previousBlockState() != 1) { start_index = comment_start_expression_.match(text).capturedStart(); }

    while (start_index >= 0)
    {
        QRegularExpressionMatch match = comment_end_expression_.match(text, start_index);
        const int end_index = match.capturedStart();
        int comment_length;

        if (end_index == -1)
        {
            setCurrentBlockState(1);
            comment_length = text.length() - start_index;
        }
        else
        {
            comment_length = end_index - start_index + match.capturedLength();
        }

        setFormat(start_index, comment_length, multi_line_comm_format_);
        start_index = comment_start_expression_.match(text, start_index + comment_length).capturedStart();
    }
}
